#include "SchmidtCAM.h"

void choose_OS_channel(int os_idx, uint32_t *reg_ptr);

int main( int argc, char *argv[] ){

    struct timeval start;
	struct timeval end;
	
	gettimeofday(&start, NULL);

/**** handle option parameters ****/
	int opt;
	opterr = 1;

	int n_row 			= 4666;	// default
	int n_col 			= 1248;	// default
	int fast_read_opt	= 0;
	int n_bytes			= 2;	// default 32bits float
	int n_sample_per_reg= 160;
	int os_idx          = 0;

	char fout_name[1024]= "tmp.bin";
	
	// int fname_set 			= -1;
	// int n_row_set 			= -1;
	// int n_col_set			= -1;
	// int fast_read_opt_set	= -1;

	while( (opt=getopt(argc,argv,"r:c:f:o:b:i:")) != -1 ){
		switch(opt){
			case 'r':
				n_row = atoi(optarg);
				printf("(%s)> Num. of vertical transfers: %d\n", __FUNCTION__, n_row);
				break;
			case 'c':
				n_col = atoi(optarg);
				printf("(%s)> Num. of horizontal transfers: %d\n", __FUNCTION__, n_col);
				break;
			case 'f':
				fast_read_opt = atoi(optarg);
				break;
			case 'o':
				sprintf(fout_name, "%s", optarg);
				printf("(%s)> data will be saved into: %s\n", __FUNCTION__, fout_name);
				break;
			case 'b':
				n_bytes = atoi(optarg);
				printf("(%s)> date format %d bytes (2 bytes: 16bits unsigned; 4 bytes: 32bits float).\n", __FUNCTION__, n_bytes);
				break;
			case 'i':
			    os_idx = atoi(optarg);
			    printf("(%s)> choose to capture and save channel:%d 's waveform.\n", __FUNCTION__, os_idx);
			    break;
			default:
				break;
		}
	}
	
	if( os_idx < 0 || os_idx > 15 ){
	    printf("\n> os_idx should be 0~15\n");
	    return 0;
	}


/**** memery map ****/

	int fd_gpio = open("/dev/mem", O_RDWR | O_SYNC);

	// ADDR_GPIO_OUT --> 0x41220000
	uint32_t *gpio_reg_ctrl = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd_gpio, ADDR_GPIO_OUT);

	// ADDR_GPIO_IN  --> 0x41210000
	uint32_t *gpio_reg_status = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd_gpio, ADDR_GPIO_IN);

	// ADDR_PL_PS_DDR_CNT --> 0x41210008
	// uint32_t *gpio_reg_pl_ps_ddr_cnt = mmap(NULL, 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd_gpio, ADDR_PL_PS_DDR_CNT);
	uint32_t *gpio_reg_pl_ps_ddr_cnt = gpio_reg_status + 2;

/*	gettimeofday(&end, NULL);*/
/*    printf("==> Normal readout used time: %g s\n", time_diff(&start, &end));*/

////////////////////////////////////////////////////////////////////////////
// choose which OS channel's waveform will be captured & saved 
    
    uint32_t *gpio_reg_fp_ctr = mmap(   NULL, 10, 
                                        PROT_READ | PROT_WRITE, 
                                        MAP_SHARED, fd_gpio, 
                                        ADDR_Float_Point_CTRL);

    choose_OS_channel( os_idx, gpio_reg_fp_ctr );
    
    usleep(10000);
////////////////////////////////////////////////////////////////////////////

	ccd_read_os_wave(gpio_reg_ctrl, 
                     gpio_reg_status, 
                     gpio_reg_pl_ps_ddr_cnt, 
                     n_row,
                     n_col,
				     n_bytes,
				     n_sample_per_reg,
                     fast_read_opt,
                     fout_name );

	munmap(gpio_reg_ctrl,10);
	munmap(gpio_reg_status,10);
	munmap(gpio_reg_pl_ps_ddr_cnt,10);
	close(fd_gpio);

	gettimeofday(&end, NULL);
    printf("==> Normal readout used time: %g s\n", time_diff(&start, &end));
    
/*    sleep(30);*/

	return 0;
}

void choose_OS_channel(int os_idx, uint32_t *reg_ptr){
    int A3 = getbit(os_idx, 3);
    int A2 = getbit(os_idx, 2);
    int A1 = getbit(os_idx, 1);
    int A0 = getbit(os_idx, 0);
    
    printf("{A3,A2,A1,A0} = {%d,%d,%d,%d}\n",A3,A2,A1,A0);
    
    if(A3==1)
        setbit(*reg_ptr, BIT_FLOAT_SPI_PS_A3);
    else
        clrbit(*reg_ptr, BIT_FLOAT_SPI_PS_A3);
        
    if(A2==1)
        setbit(*reg_ptr, BIT_FLOAT_SPI_PS_A2);
    else
        clrbit(*reg_ptr, BIT_FLOAT_SPI_PS_A2);
        
    if(A1==1)
        setbit(*reg_ptr, BIT_FLOAT_SPI_PS_A1);
    else
        clrbit(*reg_ptr, BIT_FLOAT_SPI_PS_A1);
        
    if(A0==1)
        setbit(*reg_ptr, BIT_FLOAT_SPI_PS_A0);
    else
        clrbit(*reg_ptr, BIT_FLOAT_SPI_PS_A0);
    
}
